
//% color="#007ff5" iconWidth=50 iconHeight=40
namespace bluetoothSocket{


    //% block="蓝牙设置" blockType="tag"
    export function tagtest() {}
    //% block="Start Bluetooth server[NAME]" blockType="command"
    //% NAME.shadow="string" NAME.defl="unihiker"
    export function startBTServer(parameter: any, block: any) {
        let name=parameter.NAME.code;
        name = replaceQuotationMarks(name)

        Generator.addImport(`import bluetooth\nimport threading\nimport time\nimport os`)

        Generator.addDeclaration('client_sock',`bt_recv_data = ''
client_sock = None
connected_event = threading.Event()
client_lock = threading.Lock()`)
        Generator.addCode(`def server_loop():
    global client_sock, bt_recv_data
    
    while True:  
        server_sock = None
        try:
            bt_recv_data = ''
    
            server_sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
            server_sock.bind(("", bluetooth.PORT_ANY))
            server_sock.listen(1)
            channel = server_sock.getsockname()[1]

            os.system("sudo hciconfig hci0 name unihiker")
            time.sleep(1)

            os.system("sudo bluetoothctl discoverable on")
            time.sleep(1)
            os.system(f"sudo sdptool add --channel={channel} SP")
            time.sleep(2)
            print(f"Waiting for connection...")
            while True:
                try:
                    
                    cs, client_info = server_sock.accept()
                    
                    with client_lock:
                        client_sock = cs
                    connected_event.set()
                    
                    try:
                        while True:
                            data = cs.recv(1024)
                            if not data:
                                break
                            text = data.decode("utf-8", errors="replace")
                            bt_recv_data += text
                            getdata(bt_recv_data)
                            bt_recv_data = ''
                    except bluetooth.btcommon.BluetoothError as e:
                        break
                    except Exception as e:
                        break
                    finally:
                        try:
                            cs.close()
                        except:
                            pass
                        with client_lock:
                            client_sock = None
                        connected_event.clear()
                        
                except bluetooth.btcommon.BluetoothError as e:
                    break  
                except Exception as e:
                    break  
                    
        except Exception as e:
            pass
        finally:
            if server_sock:
                try:
                    server_sock.close()
                except:
                    pass
            time.sleep(2)  



`)
Generator.addCode(`threading.Thread(target=server_loop, daemon=True).start()`)
    }



    //% block="---" 
    export function tagtest22() {}
    //% block="Start Bluetooth client and connect to server address [NAME]" blockType="command"
    //% NAME.shadow="string" NAME.defl="unihiker"
    export function startBTClient(parameter: any, block: any) {
        let name = parameter.NAME.code;
        name = replaceQuotationMarks(name)
        Generator.addImport(`import bluetooth\nimport threading`)
        Generator.addDeclaration('client_sock',`
client_sock = None
connected_event = threading.Event()
client_lock = threading.Lock()`)
        Generator.addCode(`print("Connecting...")
devices = bluetooth.discover_devices(duration=10, lookup_names=True, flush_cache=True)

addr = None
for daddr, name in devices:
    print(name,daddr)
    if name == '${name}':
        addr = daddr
        break

if not addr:
    raise RuntimeError("未找到名称为${name} 的设备")

sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
sock.connect((addr, 1))
with client_lock:
    client_sock = sock
connected_event.set()
def recv_loop(s):
    global bt_recv_data
    bt_recv_data = ''
    while True:
        try:
            data = s.recv(1024)
            if not data:
                print("Server closed connection")
                break
            text = data.decode("utf-8", errors="replace")
            bt_recv_data += text
            getdata(bt_recv_data)
            bt_recv_data = ''
        except Exception as e:
            print(f"recv err: {e}")
            break

threading.Thread(target=recv_loop, args=(client_sock,), daemon=True).start()
`)

    }


    //% block="蓝牙消息" blockType="tag"
    export function tagtest1() {}
    //% block="Bluetooth client sends message[DATA]" blockType="command"
    //% DATA.shadow="string" DATA.defl="hello"
    export function sendmess(parameter: any, block: any) {
        let data=parameter.DATA.code;

    Generator.addCode(`try:
    with client_lock:
        cs = client_sock
    if cs:
        cs.send(b${data}) 
except Exception as e:
    print(f"send err: {e}")`)

 
    }

    //% block="---" blockType=""
    export function tagtes1() {}
    //% block="Does the Bluetooth server buffer have data?" blockType="hat"
    export function serverAvailable(parameter: any, block: any) {
        Generator.addEvent("1",`getdata`,`data`)
        Generator.addCode(`global bt_recv_data
bt_recv_data = data`)


    }

    //% block="Bluetooth server retrieves cached data and then clears the cache" blockType="reporter"
    export function serverGetData(parameter: any, block: any) {
        
        Generator.addCode(`bt_recv_data`)
    }

    function replaceQuotationMarks(str:string){
            str=str.replace(/"/g, ""); //去除所有引号
            return str
    }


    
}
